home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.3 Development Libraries / SGI IRIX 6.3 Development Libraries.iso / dist6.3 / gl_dev.idb / usr / share / src / OpenGL / teach / motif / mouse.c.z / mouse.c
Encoding:
C/C++ Source or Header  |  1996-12-06  |  5.2 KB  |  204 lines

  1. /*
  2.  * mouse.c - double buffered RGBA motif program using mouse motion events
  3.  */
  4. /* compile: cc -o mouse mouse.c -lGLw -lGLU -lGL -lXm -lXt -lX11 */
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <Xm/Frame.h>
  8. #include <Xm/RowColumn.h>
  9. #include <X11/GLw/GLwMDrawA.h>
  10. #include <X11/keysym.h>
  11. #include <X11/Xutil.h>
  12. #include <GL/glx.h>
  13. #include <GL/glu.h>
  14.  
  15. static void draw_scene(void);
  16. static void initialize(void);
  17. static void update_view(int mstate, int ox, int oy, int nx, int ny);
  18.  
  19. static int attribs[] = { GLX_RGBA, GLX_RED_SIZE, 1, GLX_DOUBLEBUFFER, None};
  20.  
  21. static String fallbackResources[] = {
  22.     "*sgiMode: True",
  23.     "*useSchemes: all",
  24.     "*glxwidget.width: 300", "*glxwidget.height: 300",
  25.     "*frame.shadowType: SHADOW_IN",
  26.     NULL};
  27.  
  28. static struct {            /* global UI variables - keep them together */
  29.     XtAppContext appctx;
  30.     Widget glxwidget;
  31.     Boolean direct;
  32.     GLfloat trans[3];        /* current translation */
  33.     GLfloat rot[2];        /* current rotation */
  34. } state;
  35.  
  36. static void
  37. input(Widget w, XtPointer client_data, XtPointer call) {
  38.    char buf[31];
  39.    KeySym keysym;
  40.    XEvent *event = ((GLwDrawingAreaCallbackStruct *) call)->event;
  41.    static mstate, omx, omy, mx, my;
  42.  
  43.    switch(event->type) {
  44.    case KeyRelease:
  45.       XLookupString(&event->xkey, buf, sizeof buf, &keysym, NULL);
  46.       switch(keysym) {
  47.       case XK_Escape:
  48.      exit(EXIT_SUCCESS);
  49.      break;
  50.       default: break;
  51.       }
  52.       break;
  53.     case ButtonPress:
  54.     if (event->xbutton.button == Button2) {
  55.         mstate |= 2;
  56.         mx = event->xbutton.x;
  57.         my = event->xbutton.y;
  58.     } else if (event->xbutton.button == Button1) {
  59.         mstate |= 1;
  60.         mx = event->xbutton.x;
  61.         my = event->xbutton.y;
  62.     }
  63.     break;
  64.     case ButtonRelease:
  65.     if (event->xbutton.button == Button2)
  66.         mstate &= ~2;
  67.     else if (event->xbutton.button == Button1)
  68.         mstate &= ~1;
  69.     break;
  70.     case MotionNotify:
  71.     if (mstate) {
  72.         omx = mx;
  73.         omy = my;
  74.         mx = event->xbutton.x;
  75.         my = event->xbutton.y;
  76.         update_view(mstate, omx,mx,omy,my);
  77.     }
  78.     break;
  79.    }
  80. }
  81.  
  82. static void
  83. resize(Widget w, XtPointer client_data, XtPointer call) {
  84.    GLwDrawingAreaCallbackStruct *call_data;
  85.    call_data = (GLwDrawingAreaCallbackStruct *) call;
  86.  
  87.    glViewport(0, 0, call_data->width, call_data->height);
  88. }
  89.  
  90. static void
  91. expose(Widget w, XtPointer client_data, XtPointer call) {
  92.     GLwDrawingAreaCallbackStruct *call_data;
  93.     call_data = (GLwDrawingAreaCallbackStruct *) call;
  94.  
  95.     draw_scene();
  96. }
  97.  
  98. main(int argc, char *argv[]) {
  99.     Display        *dpy;
  100.     XVisualInfo    *visinfo;
  101.     GLXContext      glxcontext;
  102.     Widget          toplevel, frame;
  103.  
  104.     toplevel = XtOpenApplication(&state.appctx, "mouse", NULL, 0, &argc, argv,
  105.         fallbackResources, applicationShellWidgetClass, NULL, 0);
  106.     dpy = XtDisplay(toplevel);
  107.  
  108.     frame = XmCreateFrame(toplevel, "frame", NULL, 0);
  109.     XtManageChild(frame);
  110.  
  111.     /* specify visual directly */
  112.     if (!(visinfo = glXChooseVisual(dpy, DefaultScreen(dpy), attribs)))
  113.     XtAppError(state.appctx, "no suitable RGB visual");
  114.  
  115.     state.glxwidget = XtVaCreateManagedWidget("glxwidget", glwMDrawingAreaWidgetClass,
  116.     frame, GLwNvisualInfo, visinfo, NULL);
  117.     XtAddCallback(state.glxwidget, GLwNexposeCallback, expose, NULL);
  118.     XtAddCallback(state.glxwidget, GLwNresizeCallback, resize, NULL);
  119.     XtAddCallback(state.glxwidget, GLwNinputCallback, input, NULL);
  120.  
  121.     XtRealizeWidget(toplevel);
  122.  
  123.     glxcontext = glXCreateContext(dpy, visinfo, 0, GL_TRUE);
  124.     state.direct = glXIsDirect(dpy, glxcontext);
  125.     GLwDrawingAreaMakeCurrent(state.glxwidget, glxcontext);
  126.  
  127.     initialize();
  128.  
  129.     XtAppMainLoop(state.appctx);
  130. }
  131.  
  132. static void
  133. initialize(void) {
  134.     glShadeModel(GL_FLAT);
  135.     gluPerspective(40., 3.0/2.0, 0.001, 100000.0);
  136.     glTranslatef(0.0, 0.0, -3.0);
  137.     glClearColor(0.2,0.2,0.2,0.);
  138. }
  139.  
  140. static void
  141. side(void) { /* make a square translated 0.5 in the z direction */
  142.     glPushMatrix();
  143.     glTranslatef(0.0,0.0,0.5);
  144.     glRectf(-0.5,-0.5,0.5,0.5);
  145.     glPopMatrix();
  146. }
  147.  
  148. static void
  149. cube(void) { /* make a cube out of 4 squares */
  150.     glPushMatrix();
  151.     side();
  152.     glRotatef(90.,1.,0.,0.);
  153.     side();
  154.     glRotatef(90.,1.,0.,0.);
  155.     side();
  156.     glRotatef(90.,1.,0.,0.);
  157.     side();
  158.     glPopMatrix();
  159. }
  160.  
  161. static void
  162. draw_scene() {
  163.  
  164.     glClear(GL_COLOR_BUFFER_BIT);
  165.     glPushMatrix();
  166.     glTranslatef(state.trans[0], state.trans[1], state.trans[2]);
  167.     glRotatef(state.rot[0], 1.0, 0.0, 0.0);
  168.     glRotatef(state.rot[1], 0.0, 1.0, 0.0);
  169.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  170.     glColor3f(.1, .1, .8);
  171.     cube();
  172.     glScalef(0.3,0.3,0.3);
  173.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  174.     glColor3f(.8, .8, .1);
  175.     cube();
  176.     glPopMatrix();
  177.     GLwDrawingAreaSwapBuffers(state.glxwidget);
  178.     if (!state.direct) glFinish();    /* hack to improve net interactivity */
  179. }
  180.  
  181. static void
  182. update_view(int mstate, int ox, int nx, int oy, int ny) {
  183.     int dx = ox - nx;
  184.     int dy = ny - oy;
  185.  
  186.     switch(mstate) {
  187.     case 1:    /* pan */
  188.     state.trans[0] -= dx/100.;
  189.     state.trans[1] -= dy/100.;
  190.     break;
  191.     case 2:    /* rotate */
  192.     state.rot[0] += (dy * 180.0)/500.;
  193.     state.rot[1] -= (dx * 180.0)/500.;
  194. #define clamp(x) x = x > 360. ? x-360. : x < -360. ? x += 360. : x 
  195.     clamp(state.rot[0]);
  196.     clamp(state.rot[1]);
  197.     break;
  198.     case 3:    /* zoom */
  199.     state.trans[2] -= (dx+dy)/100.;
  200.     break;
  201.     }
  202.     draw_scene();
  203. }
  204.